// notification_helper.dart
import 'dart:convert';
import 'dart:io';

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;

import '../controller/notification_controller.dart';
import '../controller/order_controller.dart';
import '../controller/product_controller.dart';
import '../controller/restaurant_controller.dart';
import '../controller/splash_controller.dart';
import '../data/model/response/order_details_model.dart';
import '../data/model/response/product_model.dart';
import '../data/model/response/restaurant_model.dart';
import '../helper/route_helper.dart';
import '../util/app_constants.dart';
import '../view/screens/product/product_screen.dart';
import '../view/screens/restaurant/restaurant_screen.dart';
import '../view/screens/review/rate_review_screen.dart';

/* ──────────────────────────────────────────────────────────────── */
/*  1.  顶层函数 —— FCM 后台消息入口                                    */
/*     (✱ 必须是顶层 + @pragma('vm:entry-point'))                    */
/* ──────────────────────────────────────────────────────────────── */
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  final fln = FlutterLocalNotificationsPlugin();
  await _NotificationInternal._initLocal(fln);
  await _NotificationInternal.showNotification(message, fln, true);
}

/* ──────────────────────────────────────────────────────────────── */
/*  2.  顶层函数 —— 系统本地通知点击（后台/终止状态时调用）             */
/* ──────────────────────────────────────────────────────────────── */
@pragma('vm:entry-point')
void onDidReceiveBackgroundNotification(NotificationResponse details) {
  _NotificationInternal.onHandleNotification(details.payload);
}

/* ──────────────────────────────────────────────────────────────── */
/*  3.  对外暴露的工具类                                            */
/* ──────────────────────────────────────────────────────────────── */
class NotificationHelper {
  /// 前台初始化；在 main() 启动后调用
  static Future<void> initializeForeground(
      FlutterLocalNotificationsPlugin fln) async {
    // 本地通知初始化
    await _NotificationInternal._initLocal(fln);

    /* ——— FCM 前台通知 ——— */
    FirebaseMessaging.onMessage.listen((m) async {
      if (m.data['type'] != 'payment_success') {
        await _NotificationInternal.showNotification(m, fln, false);
      }

      // 更新业务数据
      Get.find<OrderController>().getRunningOrders(1);
      Get.find<OrderController>().getHistoryOrders(1);
      Get.find<NotificationController>().getNotificationList(true);
    });

    /* ——— 用户点击通知（App 在后台） ——— */
    FirebaseMessaging.onMessageOpenedApp
        .listen(_NotificationInternal._routeByMessage);

    /* ——— App 由终止状态冷启动时的通知 ——— */
    final initial = await FirebaseMessaging.instance.getInitialMessage();
    if (initial != null) {
      _NotificationInternal._routeByMessage(initial);
    }
  }
}

/* ──────────────────────────────────────────────────────────────── */
/*  4.  私有实现逻辑                                                */
/* ──────────────────────────────────────────────────────────────── */
class _NotificationInternal {
  /* ---------- 本地通知初始化 ---------- */
  static Future<void> _initLocal(FlutterLocalNotificationsPlugin fln) async {
    const android = AndroidInitializationSettings('notification_icon');
    const ios = DarwinInitializationSettings();
    final settings = InitializationSettings(android: android, iOS: ios);

    await fln.initialize(
      settings,
      onDidReceiveBackgroundNotificationResponse:
          onDidReceiveBackgroundNotification,
      onDidReceiveNotificationResponse: (details) =>
          onHandleNotification(details.payload),
    );
  }

  /* ---------- 本地 / 后台通知点击 ---------- */
  static Future<void> onHandleNotification(String? payload) async {
    if (payload == null) return;
    final map = json.decode(payload) as Map<String, dynamic>;
    final showType = map['showType'] as String?;
    final id = int.tryParse('${map['id']}') ?? 0;

    switch (showType) {
      case 'restaurant':
        final r = await Get.find<RestaurantController>()
            .getRestaurantDetails(Restaurant(id: id), 'notification');
        Get.toNamed(RouteHelper.getRestaurantRoute(id),
            arguments: RestaurantScreen(restaurant: r!));
        break;
      case 'food':
        final p = await Get.find<ProductController>()
            .getProductDetails(Product(id: id));
        if (p != null) {
          Get.toNamed(RouteHelper.getProductRoute(p.id!),
              arguments: ProductScreen(product: p));
        }
        break;
      case 'review':
        await _openReviewScreen();
        break;
      default:
        Get.toNamed(RouteHelper.getOrderDetailsRoute(id));
    }
  }

  /* ---------- 路由分发：FCM 点击 ---------- */
  static Future<void> _routeByMessage(RemoteMessage m) async {
    final type = m.data['show_type'];
    final id = m.data['id'];
    if (type == 'restaurant') {
      final r = await Get.find<RestaurantController>()
          .getRestaurantDetails(Restaurant(id: int.parse(id)), 'notification');
      Get.toNamed(RouteHelper.getRestaurantRoute(int.parse(id)),
          arguments: RestaurantScreen(restaurant: r!));
    } else if (type == 'food') {
      final p = await Get.find<ProductController>()
          .getProductDetails(Product(id: int.parse(id)));
      if (p != null) {
        Get.toNamed(RouteHelper.getProductRoute(p.id!),
            arguments: ProductScreen(product: p));
      }
    } else {
      final key = m.notification?.titleLocKey;
      Get.toNamed(key != null && key.isNotEmpty
          ? RouteHelper.getOrderDetailsRoute(int.parse(key))
          : RouteHelper.getNotificationRoute());
    }
  }

  /* ---------- 显示通知 ---------- */
  static Future<void> showNotification(
      RemoteMessage m, FlutterLocalNotificationsPlugin fln, bool data) async {
    final map = {'showType': m.data['show_type'], 'id': m.data['id']};
    final title = data ? m.data['title'] : (m.notification?.title ?? '');
    final body = data ? m.data['body'] : (m.notification?.body ?? '');
    final image = _extractImage(m, data);

    if (image != null && image.isNotEmpty) {
      await _showBigPicture(title, body, image, fln, map);
    } else {
      await _showBigText(title, body, fln, map);
    }
  }

  /* ---------- 工具 ---------- */
  static String? _extractImage(RemoteMessage m, bool data) {
    final raw = data
        ? m.data['image']
        : (GetPlatform.isAndroid
            ? m.notification?.android?.imageUrl
            : m.notification?.apple?.imageUrl);
    if (raw == null || raw.isEmpty) return null;
    return raw.startsWith('http')
        ? raw
        : '${AppConstants.BASE_URL}/storage/app/public/notification/$raw';
  }

  static Future<void> _showBigText(String t, String b,
      FlutterLocalNotificationsPlugin fln, Map<String, dynamic> payload) async {
    final info = BigTextStyleInformation(b,
        htmlFormatBigText: true, contentTitle: t, htmlFormatContentTitle: true);
    final android = AndroidNotificationDetails(
        'stackfood_text', 'StackFood Text',
        importance: Importance.max,
        priority: Priority.max,
        playSound: true,
        sound: const RawResourceAndroidNotificationSound('notification'),
        styleInformation: info);
    await fln.show(0, t, b, NotificationDetails(android: android),
        payload: jsonEncode(payload));
  }

  static Future<void> _showBigPicture(String t, String b, String img,
      FlutterLocalNotificationsPlugin fln, Map<String, dynamic> payload) async {
    final dir = await getApplicationDocumentsDirectory();
    final big = await _download('${dir.path}/big', img);
    final large = await _download('${dir.path}/large', img);

    final style = BigPictureStyleInformation(
      FilePathAndroidBitmap(big),
      hideExpandedLargeIcon: true,
      contentTitle: t,
      htmlFormatContentTitle: true,
      summaryText: b,
      htmlFormatSummaryText: true,
    );
    final android = AndroidNotificationDetails(
        'stackfood_pic', 'StackFood Picture',
        largeIcon: FilePathAndroidBitmap(large),
        importance: Importance.max,
        priority: Priority.max,
        playSound: true,
        sound: const RawResourceAndroidNotificationSound('notification'),
        styleInformation: style);
    await fln.show(0, t, b, NotificationDetails(android: android),
        payload: jsonEncode(payload));
  }

  static Future<String> _download(String path, String url) async {
    final res = await http.get(Uri.parse(url));
    final file = File(path);
    await file.writeAsBytes(res.bodyBytes);
    return path;
  }

  static Future<void> _openReviewScreen() async {
    final pc = Get.find<ProductController>();
    final ok = await pc.getUnreviewedOrdersData();
    if (!ok) return;
    final list = pc.unreviewedOrdersResponse?.reviewOrders;
    if (list != null && list.isNotEmpty) {
      final order = list[0];
      final od =
          await Get.find<OrderController>().getOrderDetails('${order.id}');
      if (od != null) {
        Get.until((route) => Get.isDialogOpen == false);
        final details = <Details>[...od.details ?? []];
        Get.toNamed(RouteHelper.getReviewRoute(),
            arguments: RateReviewScreen(
              orderDetailsList: details,
              deliveryMan: od.deliveryMan,
              isFoodReviewed: false,
              isFromHome: true,
              orderId: od.id.toString(),
            ));
      }
    }
  }
}

/* ──────────────────────────────────────────────────────────────── */
/*  5.  （示例）在 main.dart 中使用                                  */
/* ──────────────────────────────────────────────────────────────── */
// void main() async {
//   WidgetsFlutterBinding.ensureInitialized();
//   // 注册后台 FCM 处理
//   FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
//
//   final fln = FlutterLocalNotificationsPlugin();
//   await NotificationHelper.initializeForeground(fln);
//
//   runApp(const MyApp());
// }
